<?php

namespace IDock\Insurance\ACIC\Request;

use Exception;
use IDock\Insurance\ACIC\ACICEnums;
use IDock\Insurance\ACIC\Response\PremiumInquiryResponse;
use IDock\Visitor\Premium\PremiumChargingPileVisitor;
use IDock\Visitor\Premium\PremiumCoverageVisitor;
use IDock\Visitor\Premium\PremiumExtInfoVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\Premium\PremiumRelationVisitor;

class PremiumInquiryRequest extends AllACICRequest
{
    protected $code = 'V00';

    protected $response = PremiumInquiryResponse::class;

    /**
     * @var PremiumInquiryVisitor $visitor
     */
    protected $visitor;

    protected $urlTip = '询价';

    /**
     * @return array
     * @throws Exception
     */
    public function generate(): array
    {
        $data = [
            'Vehicle' => $this->getVehicle(),
            'ApplicationList' => ['Application' => $this->getApplication()],
            'CoverageList' => ['CoverageItem' => $this->getCoverageList()],
            'Applicant' => $this->getRelatedInfo($this->visitor->getApplicantVisitor(), 'applicant'),
            'Insured' => $this->getRelatedInfo($this->visitor->getInsuredVisitor(), 'insured'),
            'Owner' => $this->getRelatedInfo($this->visitor->getOwnerVisitor(), 'owner'),
            'AreaCode' => $this->visitor->getExtInfo('AreaCode'),
            'SpecifiedDriver' => '',
            'Taxation' => $this->getTaxation(),
            'Channel' => $this->getChannel($this->visitor->getExtInfoVisitor()),
            'RepeatModel' => '1',
            'NvhlPlyFlag' => ''
        ];
        if (!$data['CoverageList'] or !count($data['CoverageList']['CoverageItem'])) {
            unset($data['CoverageList']);
        }

        //充电桩
        if (count($this->visitor->getChargingPileVisitorList())) {
            $data['ChargingPostInfoList'] = ['ChargingPostInfo' => $this->getChargingPileInfo()];
        }

        //驾驶人
        //$data['SpecifiedDriver'] = $this->getDriverInfo($this->visitor->getOwnerVisitor());

        //非车参数
        if ($this->visitor->getNonCarInquiryVisitor()->getNonCarList()) {
            $data['NvhlPlyFlag'] = '1';
        }

        return $data;
    }

    /**
     * 车辆信息
     * @return array
     */
    private function getVehicle(): array
    {
        $vehicleVisitor = $this->visitor->getVehicleVisitor();

        $motorTypeCode = '11';

        $carKindCode = $vehicleVisitor->carKindCode;

        if ($carKindCode == '100') {
            $motorTypeCode = $vehicleVisitor->vehicleSeat < 6 ? '11' : '12';
        }

        if ($carKindCode == '200' or $carKindCode == '210') {
            if ($vehicleVisitor->vehicleTonnage < 2000) {
                $motorTypeCode = '21';
            }
            if ($vehicleVisitor->vehicleTonnage >= 2000 and $vehicleVisitor->vehicleTonnage < 5000) {
                $motorTypeCode = '22';
            }

            if ($vehicleVisitor->vehicleTonnage >= 5000 and $vehicleVisitor->vehicleTonnage < 10000) {
                $motorTypeCode = '23';
            }
            if ($vehicleVisitor->vehicleTonnage >= 10000) {
                $motorTypeCode = '24';
            }
        }
        $usageTypeCode = '';

        $useNatureCode = $vehicleVisitor->useNatureCode . $vehicleVisitor->attachNature;

        if ($useNatureCode == '0101') {
            $usageTypeCode = '210';
        }
        if ($useNatureCode == '0102') {
            $usageTypeCode = '230';
        }
        if ($useNatureCode == '0103') {
            $usageTypeCode = '220';
        }

        return [
            'LicensePlateNo' => $vehicleVisitor->licenseNo,
            'MotorTypeCode' => $motorTypeCode,
            'MotorUsageTypeCode' => $usageTypeCode,
            'FirstRegisterDate' => $vehicleVisitor->firstRegisterDate,
            'VIN' => $vehicleVisitor->vin,
            'EngineNo' => $vehicleVisitor->engineNo,
            'Model' => $vehicleVisitor->vehicleModelCode,
            'ReplacementValue' => $vehicleVisitor->vehiclePrice,
            'ChangedVehlValue' => $vehicleVisitor->actualValue,
            //'ChangedVehlValue' => 0,
            'TransferDate' => $vehicleVisitor->transferDate,
            'BrandType' => '',
            'DisplaceMent' => $vehicleVisitor->vehicleExhaust,
            'Power' => $vehicleVisitor->power,
            'Whole_Weight' => $vehicleVisitor->wholeWeight,
            //车队标识
            'FleetFlag' => $this->visitor->getExtInfo('FleetFlag', '0'),
            //车队号
            'FleetNo' => $this->visitor->getExtInfo('FleetNo'),
            //进口车
            'IpmORLoc' => array_search($vehicleVisitor->vehicleImport, ACICEnums::$importFlag),
            //外地车标志
            'EcdemicVehicleFlag' => $this->visitor->getExtInfo('EcdemicVehicleFlag', '0'),
            //
            'CarName' => $vehicleVisitor->vehicleName,
            'RatedPassengerCapacity' => $vehicleVisitor->vehicleSeat,
            'Tonnage' => (int)$vehicleVisitor->vehicleTonnage,
            'TonnageEx' => (int)$vehicleVisitor->vehicleTonnage / 1000,
            'CSeat' => $vehicleVisitor->vehicleSeat,
            'LoanVehicleFlag' => (int)$this->visitor->getExtInfoVisitor()->isLoanCar,
            'RegVchlType' => $vehicleVisitor->vehicleStyleCode,
            'FuelType' => ACICEnums::$energyType1[$vehicleVisitor->energyTypeCode],
            'NewVchlFlag' => (int)$vehicleVisitor->isNewVehicle,
            //广东交管车辆使用性质
            'RegVchlUseType' => '',
            //车辆号牌种类
            'LicensePlateType' => $vehicleVisitor->licenseTypeCode,
            'RegVchlKey' => '',
            'RegVchlCheckCode' => '',
            'SaleCompany' => '',
            'SaleAreaCode' => '',
            'Sale4SFlag' => '',
            'SHSumLimitType' => '',
            'PureRange' => $vehicleVisitor->pureRange,
            'OtherEnergyTypeDesc' => '',
            'CAScore' => $this->visitor->getExtInfo('CAScore'),
            'MaxDesignSpeed' => '',
        ];
    }

    /**
     * 保单信息
     * @return array
     */
    private function getApplication(): array
    {
        $applicationList = [];

        //商业险
        if ($this->visitor->getBiStartData()) {
            $biData = [
                'ProdNo' => ACICEnums::$VCI,
                'LastPolicyNo' => '',
                'BillDate' => date('Y-m-d'),
                //'EffectiveDate' => date('Y-m-d 00:00:00', strtotime($this->visitor->getBiStartData())),
                'EffectiveDate' => $this->visitor->getBiStartData(),
                //'ExpireDate' => $this->visitor->getBiEndData() ? date('Y-m-d 23:59:59', strtotime($this->visitor->getBiEndData())) : '',
                'ExpireDate' => $this->visitor->getBiEndData(),
                'AreaCode' => $this->visitor->getExtInfo('AreaCode'),
                'AgentCode' => $this->visitor->getExtInfo('AgentCode'),
                'AgentContract' => $this->visitor->getExtInfo('AgentContract'),
                'ExpectDiscount' => $this->visitor->getExtInfoVisitor()->expectedDiscount,
                'SpecialContact' => $this->visitor->getExtInfo('SpecialContact'),
                'IsAgriculture' => '2',
                'IsForeign' => '0',
                'IsManufacture' => '0',
                'LitigationType' => '1',
                'LitigationOrg' => '',
                'OrgCode' => $this->visitor->getExtInfo('OrgCode'),
                'AgtSlsName' => '',
                'AgtSlsPhone' => '',
                'ImmeEffFlag' => date('H:i:s', strtotime($this->visitor->getBiStartData())) == '00:00:00' ? 0 : 1,
                'QueryNo' => $this->visitor->getExtInfo('QueryNo'),
                'PreFreeDiscount' => $this->visitor->getExtInfoVisitor()->selfPricingFactor,
                'NewFuelVhlFlag' => (int)$this->visitor->isNewEnergy,
                'OrgCodeID' => '',
                'NewTransferDateFlag' => '',
            ];
            if ($biData['ImmeEffFlag']) {
                $biData['ExpireDate'] = date('Y-m-d 00:00:00', strtotime($biData['ExpireDate']));
            }

            $applicationList[] = $biData;
        }

        //交强险
        if ($this->visitor->getCiStartData()) {
            $applicationList[] = [
                'ProdNo' => ACICEnums::$TCI,
                'LastPolicyNo' => '',
                'BillDate' => date('Y-m-d'),
                //'EffectiveDate' => date('Y-m-d 00:00:00', strtotime($this->visitor->getCiStartData())),
                'EffectiveDate' => $this->visitor->getCiStartData(),
                //'ExpireDate' => $this->visitor->getCiEndData() ? date('Y-m-d 23:59:59', strtotime($this->visitor->getCiEndData())) : '',
                'ExpireDate' => $this->visitor->getCiEndData(),
                'AreaCode' => $this->visitor->getExtInfo('AreaCode'),
                'AgentCode' => $this->visitor->getExtInfo('AgentCode'),
                'AgentContract' => $this->visitor->getExtInfo('AgentContract'),
                'ExpectDiscount' => $this->visitor->getExtInfoVisitor()->expectedDiscount,
                'SpecialContact' => $this->visitor->getExtInfo('SpecialContact'),
                'IsAgriculture' => '2',
                'IsForeign' => '0',
                'IsManufacture' => '0',
                'LitigationType' => '1',
                'LitigationOrg' => '',
                'OrgCode' => $this->visitor->getExtInfo('OrgCode'),
                'AgtSlsName' => '',
                'AgtSlsPhone' => '',
                'ImmeEffFlag' => date('H:i:s', strtotime($this->visitor->getCiStartData())) == '00:00:00' ? 0 : 1,
                'QueryNo' => $this->visitor->getExtInfo('QueryNo'),
                'PreFreeDiscount' => $this->visitor->getExtInfoVisitor()->selfPricingFactor,
                'NewFuelVhlFlag' => (int)$this->visitor->isNewEnergy,
                'OrgCodeID' => '',
                'NewTransferDateFlag' => '',
            ];
        }

        return $applicationList;
    }

    /**
     * 险种信息
     * @return array
     * @throws Exception
     */
    private function getCoverageList(): array
    {
        $coverageList = [];

        /*** @var PremiumCoverageVisitor $coverageVisitor */
        foreach ($this->visitor->getCoverageVisitorList() as $coverageVisitor) {

            $coverage = $coverageVisitor->coverageCode;

            //剔除交强险代码
            if ($coverage == 'C01001') {
                continue;
            }

            //新能源险种变换
            $type = substr($coverage, '1', '1');

            if ($type == '1' and !in_array($coverage, ['C16001', 'C16002', 'C16003', 'C16004', 'C16005'])) {
                $coverage = 'C0' . substr($coverage, '2', 4);
            }

            $item = [
                'CoverageCode' => ACICEnums::$coverageCode[$coverage],
                'SumLimit' => $coverageVisitor->amount,
                'FreeFlag' => '1',
                'FreeNum' => '',
                'DayFee' => '0',
                'DaySeatNum' => '0',
                'GlassType' => '',
                'DRSRate' => '0',
                'AbRate' => '',
                'ServiceCount' => $coverageVisitor->serviceTimes,
                'LimitTimes' => ''
            ];

            //车损险绝对免赔额
            if ($coverage == 'C02001' and $coverageVisitor->deductionLimit) {
                $item['FreeNum'] = ACICEnums::$deductionLimit[$coverageVisitor->deductionLimit];
            }

            //指定修理厂险修理期间费用补偿险单位保额
            if ($coverage == 'C02003' or $coverage == 'C12003') {
                $item['DayFee'] = $coverageVisitor->unitAmount;
                $item['DaySeatNum'] = $coverageVisitor->quantity;
            }

            //乘客险座位数
            if ($coverage == 'C05001') {
                $item['DayFee'] = $coverageVisitor->unitAmount;
                $item['DaySeatNum'] = $this->visitor->getVehicleVisitor()->vehicleSeat - 1;
            }
            //指定修理厂费率
            if ($coverage == 'C02003') {
                $item['DRSRate'] = $coverageVisitor->rate;
            }

            if ($coverageVisitor->deductionRate) {
                $item['AbRate'] = (string)$coverageVisitor->deductionRate / 100;
            }

            //服务次数验证
            //道路救援
            if ($coverageVisitor->coverageCode == 'C08001' or $coverageVisitor->coverageCode == 'C18001') {
                if (!in_array($coverageVisitor->serviceTimes, [2, 7, 12, 17, 22])) {
                    throw new Exception('道路救援的服务次数，只支持2、7、12、17、22次');
                }
            }

            $coverageList[] = $item;
        }

        return $coverageList;
    }

    /**
     * 关系人信息
     * @param PremiumRelationVisitor $relatedIVisitor
     * @param string $type
     * @return array
     */
    private function getRelatedInfo(PremiumRelationVisitor $relatedIVisitor, string $type = ''): array
    {
        $data = [
            'Name' => $relatedIVisitor->name,
            'CertificateType' => ACICEnums::$certificateTypeCode[$relatedIVisitor->certificateTypeCode],
            'CertificateNo' => $relatedIVisitor->certificateNo,
            'Contact' => $relatedIVisitor->name,
            'Phone' => $relatedIVisitor->mobile,
            'Address' => $relatedIVisitor->address,
            'OrganizationType' => '',
            'Age' => '',
            'Gender' => '',
            'Email' => $relatedIVisitor->email,
            //与车辆关系
            'VchlOwnership' => '2',
            'Birthday' => '',
            'Type' => '',
            'PostCode' => '',
            'AddressDetail' => [
                'Flag' => '0'
            ],
            'InsuredRelation' => '',
            'CustomerDetail' => [
                'IDStartDate' => $relatedIVisitor->certificateStartDate,
                'IDEndDate' => $relatedIVisitor->certificateEndDate,
                'Nation' => '',
                'Income' => '10',
                'WorkOrg' => '',
                //职业明细信息
                'CareerDetail' => [
                    'FirstCode' => '40',
                    'SecondCode' => '4001',
                    'CareerCode' => '9900000',
                ],
                //机构明细信息
                'OrgDetail' => [
                    'Operate' => '',
                    'IndustryCode' => '',
                    'RegAmt' => '',
                    'RepName' => '',
                    'RepIDType' => '',
                    'RepIDNo' => '',
                    'RepIDStartDate' => '',
                    'RepIDEndDate' => '',
                    'ManName' => '',
                    'ManIDType' => '',
                    'ManIDNo' => '',
                    'ManIDStartDate' => '',
                    'ManIDEndDate' => '',
                    'OpeName' => '',
                    'OpeIDType' => '',
                    'OpeIDNo' => '',
                    'OpeIDStartDate' => '',
                    'OpeIDEndDate' => '',
                ],
                //上海实名支付相关客户信息
                'SHPayInfo' => [
                    'PhonePersonName' => '',
                    'PhonePersonCertType' => '',
                    'PhonePersonCertNo' => '',
                    'CompanyOperName' => '',
                    'CompanyOperCertType' => '',
                    'CompanyOperCertNo' => '',
                    'CompanyOperPhone' => '',
                    'CompanyOperType' => '',
                    'CompanyOperEmail' => '',
                ],
            ]
        ];

        //单位性质
        if ($relatedIVisitor->typeCode == 'R1') {
            $data['OrganizationType'] = '001';
        } else {
            $data['OrganizationType'] = '100';
        }

        //年龄
        //个人
        //if ($applicantVisitor->certificateTypeCode == '01') {
        //    $birthday = substr($applicantVisitor->certificateNo, 6, 8);
        //    if ($birthday) {
        //        $data['Birthday'] = date('Y-m-d', strtotime($birthday));
        //
        //        $year = substr($birthday, 0, 4);
        //        $age = (string)(date('Y') - $year);
        //        $data['Age'] = $age;
        //    }
        //
        //
        //
        //}

        //团体

        if ($type == 'owner') {
            $data['OwnerName'] = $data['Name'];
            unset($data['Name']);
        }

        return $data;
    }

    /**
     * 车船税信息
     * @return array
     */
    private function getTaxation(): array
    {
        $carTaxVisitor = $this->visitor->getCarTaxVisitor();
        $taxTypeCode = $carTaxVisitor->taxTypeCode;

        //完税
        if ($taxTypeCode == 'T02') {
            $taxPaid = [
                'TaxDepartmentCode' => $carTaxVisitor->taxDepartmentCode,
                'TaxDepartment' => $carTaxVisitor->taxDepartment,
                'TaxDocumentNumber' => $carTaxVisitor->taxDocumentNumber,
                'TaxDocumentDate' => $carTaxVisitor->taxDocumentDate,
                'TaxPaidAreaCode' => $carTaxVisitor->taxPaidAreaCode,
            ];
        }

        //减税
        if ($taxTypeCode == 'T03' or $taxTypeCode == 'T04') {
            $taxDerate = [
                'DeductionDueCode' => ACICEnums::$taxReductionReasonCode[$carTaxVisitor->taxReductionReasonCode],
                'DeductionDueType' => $carTaxVisitor->taxReductionCode,
                'DeductionDueProportion' => $carTaxVisitor->taxFreeRate,
                'Deduction' => $carTaxVisitor->taxExemption,
                'DeductionDocumentNumber' => $carTaxVisitor->taxDocumentNumber,
                'TaxDepartmentCode' => $carTaxVisitor->taxDepartmentCode,
                'TaxDepartment' => $carTaxVisitor->taxDepartment,
            ];
        }

        return [
            'TaxTermTypeCode' => '08',
            'TaxConditionCode' => ACICEnums::$taxTypeCode[$this->visitor->getCarTaxVisitor()->taxTypeCode],
            'TaxRegistryNumber' => $carTaxVisitor->taxDocumentNumber,
            'TaxPayerName' => $this->visitor->getOwnerVisitor()->name,
            'TaxPayerIdentificationCode' => $this->visitor->getOwnerVisitor()->certificateNo,
            'DeclareDate' => date('Y-m-d'),
            'CurrentTaxDue' => [
                'TaxLocationCode' => $this->visitor->getExtInfo('AreaCode'),
                'TaxStartDate' => $carTaxVisitor->taxStartDate,
                'TaxEndDate' => $carTaxVisitor->taxEndDate,
                'TaxUnitTypeCode' => '',
                'UnitRate' => '',
                'AnnualTaxAmount' => '',
                'Paid' => $taxPaid ?? [],
                'Derate' => $taxDerate ?? [],
                'TaxDue' => '',
                'ExceedDate' => '',
                'ExceedDaysCount' => '',
                'OverDue' => '',
                'TotalAmount' => '',
            ],
            'Declare_Status_IA' => ''
        ];
    }

    /**
     * 充电桩信息
     * @return array
     */
    private function getChargingPileInfo(): array
    {
        $list = [];
        foreach ($this->visitor->getChargingPileVisitorList() as $value) {
            /*** @var  $value PremiumChargingPileVisitor */

            $data = [
                'CPNo' => $value->seqNo,
                'CPType' => $value->chargingPileType,
                'CPCode' => $value->chargingPileCode,
                'CPAddress' => $value->chargingPileAddress,
                'CPAddressType' => ACICEnums::$chargingPileAddressType[$value->chargingPileAddressType],
                'CPKind' => ACICEnums::$chargingPileKind[$value->chargingPileKind],
                'CPYearLimit' => ACICEnums::$chargingPileYearLimit[$value->chargingPileYearLimit],
                'LossSumlimit' => $value->lossAmount,
                'LiabilitySumlimit' => $value->liabilityAmount,
            ];
            $list[] = $data;
        }

        return $list;
    }

    /**
     * 驾驶员信息
     * @param PremiumRelationVisitor $relatedIVisitor
     * @return array
     */
    private function getDriverInfo(PremiumRelationVisitor $relatedIVisitor): array
    {
        return [
            'Name' => $relatedIVisitor->name,
            'CertificateType' => $relatedIVisitor->certificateTypeCode,
            'CertificateNo' => $relatedIVisitor->certificateNo,
            'Age' => '',
            'Gender' => '',
            'DriverTypeCode' => '',
            'LicenseNo' => '',
            'LicenseStatusCode' => '',
            'LicensedDate' => '',
        ];
    }

    /**
     * 业务渠道信息
     * @param PremiumExtInfoVisitor $extInfoVisitor
     * @return array
     */
    private function getChannel(PremiumExtInfoVisitor $extInfoVisitor): array
    {
        $channel = [];
        $argc = $extInfoVisitor->argc;

        $channel['BusinessSrc'] = $argc['BusinessSrc'] ?? '';
        $channel['ChannelType'] = $argc['ChannelType'] ?? '';
        $channel['ChannelSubType'] = $argc['ChannelSubType'] ?? '';
        $channel['SalerCode'] = $argc['SalerCode'] ?? '';
        $channel['SalerName'] = $argc['SalerName'] ?? '';
        $channel['OperatorCode'] = $argc['OperatorCode'] ?? '';
        $channel['AgentCode'] = $argc['AgentCode'] ?? '';
        $channel['AgentContract'] = $argc['AgentContract'] ?? '';
        $channel['AgentSubContract'] = $argc['AgentSubContract'] ?? '';
        $channel['AreaFlag'] = $argc['AreaFlag'] ?? '';
        $channel['CountryCode'] = $argc['CountryCode'] ?? '';
        $channel['ProjectCode'] = $argc['ProjectCode'] ?? '';
        $channel['SaleGroupFlag'] = $argc['SaleGroupFlag'] ?? '';

        return array_filter($channel);
    }
}
